#pragma once
#include "IGameState.h"
#include "../SGD Wrappers/SGD_Handle.h"
#include "../SGD Wrappers/SGD_Declarations.h"
#include "../SGD Wrappers/SGD_Geometry.h"
#include "WorldManager.h"
//forward declarations
class Entity;
class Player;
class Enemy;
class EntityManager;
class BitmapFont;
class ParticleManager;
class Menu;
class MenuCursor;
class Lightorb;
class Zone;
class animation;
class Emitter;

class GamePlayState : public IGameState
{
public:
	//Singleton accessor
	static GamePlayState* GetInstance(int i=-1);

	//IGameStateInterface
	virtual void Enter() override; //load resources
	virtual void Exit() override; //unload resources
	virtual bool Input() override; //handle user input
	virtual void Update(float elapsedTime) override; //update entities
	virtual void Render() override; //render entities/menu items

	//Factory methods
	Player* CreatePlayer();
	Enemy* CreateEnemy();
	Entity* CreateProjectile(Enemy* owner,void*data=nullptr) const;
	Entity* FireGrapple(Entity* owner, Planets*p = nullptr);
	Planets* CreatePlanet();
	Lightorb* CreateLightorb();
	void LoadEmitter(Emitter&load);

	EntityManager*GetEntityManager(){ return entities; }

	Player* GetPlayer() const { return player; }

	bool OutOfBounds(Entity *);
	bool WinCheck();
	void PopulateNext();

	void DragMap(float elapsedTime);

	bool GetMapPause() const { return mapPause; }
	BitmapFont* GetGameFont() const { return gamefont; }

	bool GetPlayed() const { return playedBefore; }
	void SetPlayed(bool p) { playedBefore = p; }

private:
	GamePlayState() = default;
	virtual ~GamePlayState() = default;
	GamePlayState(const GamePlayState&) = delete;
	GamePlayState& operator=(const GamePlayState&) = delete;

	//Message manager
	SGD::MessageManager* messages = nullptr;

	//SGD wrappers
	SGD::AudioManager* audio = nullptr;
	SGD::GraphicsManager* graphics = nullptr;
	SGD::InputManager* input = nullptr;

	// Message Callback Function:
	static void MessageProc(const SGD::Message* pMsg);

	//mouse position for zooming out
	SGD::Point zmPos;

	//Entities
	EntityManager* entities = nullptr;
	Player* player = nullptr;
	Enemy* tempEnemy = nullptr;
	Enemy* tempEnemy2 = nullptr;
	
	//Particles
	ParticleManager*particles = nullptr;

	//Pause the game
	bool paused = false;
	bool mapPause = false;

	//Font
	BitmapFont* font = nullptr;

	WorldManager world;

	//Menu
	Menu* menu = nullptr;
	MenuCursor* cursor = nullptr;
	Menu* saveOptions;
	MenuCursor* saveCurs;
	int cursPos = 0;
	int saveCPos = 0;
	std::string toSave;
	bool saveDLG = false;
	bool mouseInput = false;

	/*DEBUG VARIABLES GO HERE*/
	Zone* zone = nullptr;

	//loading 
	int savefile = -1;
	void Loadfile();
	void Savefile();

	SGD::HAudio music = SGD::INVALID_HANDLE;
	//SGD::HAudio losemusic = SGD::INVALID_HANDLE;
	SGD::HTexture bg = SGD::INVALID_HANDLE;
	SGD::HTexture arrow = SGD::INVALID_HANDLE;
	animation* animationArrow = nullptr;
	
	BitmapFont* gamefont = nullptr;

	unsigned int activeZoneCount = 0;
	float arrowtimer = 0;
	float arrowactivatetimer = 30;

	//has the player played before?
	bool playedBefore = false;
};
